package cn.dakaqi.open.api.v1;

import cn.dakaqi.entities.user.User;
import cn.dakaqi.entities.user.Volunteer;
import cn.dakaqi.services.user.UserService;
import cn.dakaqi.services.user.VolunteerService;
import cn.dakaqi.util.ConfigUtil;
import cn.dakaqi.utils.JsonResult;
import cn.dakaqi.utils.exception.ServiceRuntimeException;
import cn.dakaqi.utils.redis.RedisClientTemplate;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wordnik.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springside.modules.web.MediaTypes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by chunyang on 2016/4/7.
 * 用户
 */
@RestController
@RequestMapping(value = "/api/v1/account")
@Slf4j
@Api(value = "用户API")
public class AccountRestController {
    @Autowired
    UserService userService;
    @Autowired
    VolunteerService volunteerService;
    @Autowired
    private Validator validator;
    @Resource
    private RedisClientTemplate redisClientTemplate;

    @RequestMapping(method = RequestMethod.GET, produces = MediaTypes.JSON_UTF_8)
    public List<User> list() {
        return userService.getAllUser();
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MediaTypes.JSON_UTF_8)
    public ResponseEntity<?> get(@PathVariable("id") Long id) {
        log.info("查询编号为(" + id + ")的用户信息");
        JsonResult jsonResult = new JsonResult();
        try {
            User user = userService.findOne(id);
            if (user == null) {
                String message = "用户不存在(id:" + id + ")";
                log.warn(message);
                jsonResult.setMessage(message);
                jsonResult.setCode(JsonResult.CODE_FAIL);
                return new ResponseEntity(jsonResult, HttpStatus.OK);
            }
            Map<String, Object> resultMap = new HashMap<String, Object>();
            resultMap.put("user", user);
            jsonResult.setData(resultMap);
        } catch (ServiceRuntimeException e) {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
        }
        return new ResponseEntity(jsonResult, HttpStatus.OK);
    }

    @ResponseBody
    @RequestMapping(value = "/login", method = RequestMethod.POST, consumes = MediaTypes.JSON, produces = MediaTypes.JSON_UTF_8)
    public ResponseEntity<?> login(@RequestBody String param, HttpServletResponse response, HttpSession session) {
        JsonResult result = new JsonResult();
        try {
            //检查非空
            if (StringUtils.isBlank(param)) {
                String message = "账号和密码不能为空";
                result.setMessage(message);
                result.setCode(JsonResult.CODE_FAIL);
                return new ResponseEntity(result, HttpStatus.OK);
            }
            JSONObject jsonObject = JSON.parseObject(param);
            String mobile = jsonObject.getString("mobile");
            String password = jsonObject.getString("password");
            String area = jsonObject.getString("area");
            double lng = jsonObject.getDoubleValue("lng");
            double lat = jsonObject.getDoubleValue("lat");

            if (StringUtils.isBlank(mobile)) {
                String message = "账号不能为空";
                result.setMessage(message);
                result.setCode(JsonResult.CODE_FAIL);
                return new ResponseEntity(result, HttpStatus.OK);
            }
            if (StringUtils.isBlank(password)) {
                String message = "密码不能为空";
                result.setMessage(message);
                result.setCode(JsonResult.CODE_FAIL);
                return new ResponseEntity(result, HttpStatus.OK);
            }
            User user = userService.login(mobile, password, area, lng, lat);
            if (user != null) {
                Volunteer volunteer = this.volunteerService.findByUserId(user.getId());

                String token = RandomStringUtils.randomAlphanumeric(8);

                redisClientTemplate.hset("login", user.getId().toString(), token);

                response.addHeader("token", token);
                session.setAttribute("userId", user.getId());

                result.setMessage("登录成功");
                result.setCode(JsonResult.CODE_SUCCESS);
                result.setData(volunteer);
                return new ResponseEntity(result, HttpStatus.OK);
            } else {
                String message = "账号或密码不正确";
                result.setMessage(message);
                result.setCode(JsonResult.CODE_FAIL);
                return new ResponseEntity(result, HttpStatus.OK);
            }
        } catch (ServiceRuntimeException e) {
            e.printStackTrace();
            result.setCode(JsonResult.CODE_FAIL);
            result.setMessage(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(JsonResult.CODE_FAIL);
            result.setMessage(e.getMessage());
        }
        return new ResponseEntity(result, HttpStatus.OK);

    }

    @RequestMapping(value = "/create", method = RequestMethod.POST,  consumes = MediaTypes.JSON, produces = MediaTypes.JSON_UTF_8)
    public ResponseEntity<?> create(@RequestBody String param) {
        JsonResult result = new JsonResult();
        try {
            // 调用JSR303 Bean Validator进行校验, 异常将由RestExceptionHandler统一处理.
            //BeanValidators.validateWithException(validator, account);
            //检查非空
            //String param = JSON.toJSONString(account);
            if (StringUtils.isBlank(param)) {
                String message = "数据不能为空";
                result.setMessage(message);
                result.setCode(JsonResult.CODE_FAIL);
                return new ResponseEntity(result, HttpStatus.OK);
            }
            userService.saveUser(param, ConfigUtil.getClientId());
            result.setMessage("注册成功");
            result.setCode(JsonResult.CODE_SUCCESS);
            return new ResponseEntity(result, HttpStatus.OK);
        } catch (ConstraintViolationException e) {
            e.printStackTrace();
            result.setMessage(e.getMessage());
            result.setCode(JsonResult.CODE_FAIL);
            return new ResponseEntity(result, HttpStatus.OK);
        } catch (ServiceRuntimeException e) {
            e.printStackTrace();
            result.setMessage(e.getMessage());
            result.setCode(JsonResult.CODE_FAIL);
            return new ResponseEntity(result, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(JsonResult.CODE_FAIL);
            result.setMessage(e.getMessage());
            return new ResponseEntity(result, HttpStatus.OK);
        }
    }

    @RequestMapping(value = "/modifypasswd", method = RequestMethod.POST, consumes = MediaTypes.JSON, produces = MediaTypes.JSON_UTF_8)
    public ResponseEntity<?> modifypasswd(@RequestBody String param) {
        JsonResult result = new JsonResult();
        try {
            //String param = JSON.toJSONString(modifyPwd);
            userService.updatePassd(param);
            result.setMessage("密码修改成功");
            result.setCode(JsonResult.CODE_SUCCESS);
        } catch (Exception e) {
            e.printStackTrace();
            result.setMessage(e.getMessage());
            result.setCode(JsonResult.CODE_FAIL);
        }
        return new ResponseEntity(result, HttpStatus.OK);
    }

    @RequestMapping(value = "/register/sendCode/{mobile}", method = RequestMethod.GET, produces = MediaTypes.JSON_UTF_8)
    public ResponseEntity<?> sendCodeByRegister(@PathVariable("mobile") String mobile) {
        JsonResult result = new JsonResult();
        try {
            if (StringUtils.isBlank(mobile)) {
                result.setMessage("手机不能为空");
                result.setCode(JsonResult.CODE_FAIL);
                return new ResponseEntity(result, HttpStatus.OK);
            }
            User user = this.userService.findByMobile(mobile);
            if (null != user) {
                result.setMessage("手机号已存在");
                result.setCode(JsonResult.CODE_FAIL);
                return new ResponseEntity(result, HttpStatus.OK);
            }
            this.userService.sendVerifierCode(mobile.trim());
            result.setCode(JsonResult.CODE_SUCCESS);
            result.setMessage("验证码已发送");
        } catch (ServiceRuntimeException e) {
            e.printStackTrace();
            result.setMessage(e.getMessage());
            result.setCode(JsonResult.CODE_FAIL);
            return new ResponseEntity(result, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(JsonResult.CODE_FAIL);
            result.setMessage(e.getMessage());
            return new ResponseEntity(result, HttpStatus.OK);
        }
        return new ResponseEntity(result, HttpStatus.OK);
    }

    @RequestMapping(value = "/findpasswd/sendCode/{mobile}", method = RequestMethod.GET, produces = MediaTypes.JSON_UTF_8)
    public ResponseEntity<?> sendCodeByfindpasswd(@PathVariable("mobile") String mobile) {
        log.info(mobile);
        JsonResult result = new JsonResult();
        try {
            if (StringUtils.isBlank(mobile)) {
                result.setMessage("手机不能为空");
                result.setCode(JsonResult.CODE_FAIL);
                return new ResponseEntity(result, HttpStatus.OK);
            }
            User user = this.userService.findByMobile(mobile);
            if (null == user) {
                result.setMessage("手机号不存在");
                result.setCode(JsonResult.CODE_FAIL);
                return new ResponseEntity(result, HttpStatus.OK);
            }
            this.userService.sendVerifierCode(mobile.trim());
            result.setCode(JsonResult.CODE_SUCCESS);
            result.setMessage("验证码已发送");
        } catch (ServiceRuntimeException e) {
            e.printStackTrace();
            result.setMessage(e.getMessage());
            result.setCode(JsonResult.CODE_FAIL);
            return new ResponseEntity(result, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(JsonResult.CODE_FAIL);
            result.setMessage(e.getMessage());
            return new ResponseEntity(result, HttpStatus.OK);
        }
        return new ResponseEntity(result, HttpStatus.OK);
    }

    @RequestMapping(value = "/mobile/{mobile}", method = RequestMethod.GET, produces = MediaTypes.JSON_UTF_8)
    public ResponseEntity<?> exitMobile(@PathVariable("mobile") String mobile) {
        log.info(mobile);
        JsonResult result = new JsonResult();
        try {
            //查询当前手机是否已注册
            User user = this.userService.findByMobile(mobile);
            if (null != user) {
                result.setMessage("手机已被注册");
                result.setCode(JsonResult.CODE_FAIL);
            }
        } catch (ServiceRuntimeException e) {
            e.printStackTrace();
            result.setMessage(e.getMessage());
            result.setCode(JsonResult.CODE_FAIL);
            return new ResponseEntity(result, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(JsonResult.CODE_FAIL);
            result.setMessage(e.getMessage());
            return new ResponseEntity(result, HttpStatus.OK);
        }
        return new ResponseEntity(result, HttpStatus.OK);
    }

    /**
     * 第三方登录，邦定手机
     * @return
     */
    @RequestMapping(value = "/bundMobile", method = RequestMethod.POST, consumes = MediaTypes.JSON, produces = MediaTypes.JSON_UTF_8)
    public ResponseEntity<?> bundMobile(@RequestBody String param) {
        JsonResult jsonResult = new JsonResult();

        try {
            //String param = JSON.toJSONString(bundMobile);
            if (StringUtils.isBlank(param)) {
                jsonResult.setCode(JsonResult.CODE_FAIL);
                jsonResult.setMessage("手机号不能为空");
                return new ResponseEntity(jsonResult, HttpStatus.OK);
            }
            userService.bundMobile(param);
            jsonResult.setCode(JsonResult.CODE_SUCCESS);
            jsonResult.setMessage("手机邦定成功");
            return new ResponseEntity(jsonResult, HttpStatus.OK);
        } catch (ServiceRuntimeException e) {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
            return new ResponseEntity(jsonResult, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
            return new ResponseEntity(jsonResult, HttpStatus.OK);
        }
    }

    @RequestMapping(value = "/setNewPasswd", method = RequestMethod.POST, consumes = MediaTypes.JSON, produces = MediaTypes.JSON_UTF_8)
    public ResponseEntity<?> setNewPasswd(@RequestBody String param) {
        JsonResult jsonResult = new JsonResult();

        try {
            //String param = JSON.toJSONString(setNewPwd);
            if (StringUtils.isBlank(param)) {
                jsonResult.setCode(JsonResult.CODE_FAIL);
                jsonResult.setMessage("手机号不能为空");
                return new ResponseEntity(jsonResult, HttpStatus.OK);
            }
            userService.setNewPasswd(param);
            return new ResponseEntity(jsonResult, HttpStatus.OK);
        } catch (ServiceRuntimeException e) {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
            return new ResponseEntity(jsonResult, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
            return new ResponseEntity(jsonResult, HttpStatus.OK);
        }

    }

    @RequestMapping(value = "/updateMobile", method = RequestMethod.POST, consumes = MediaTypes.JSON, produces = MediaTypes.JSON_UTF_8)
    public ResponseEntity<?> updateMobile(@RequestBody String param) {
        JsonResult jsonResult = new JsonResult();

        try {
            //String param = JSON.toJSONString(updateMobile);
            if (StringUtils.isBlank(param)) {
                jsonResult.setCode(JsonResult.CODE_FAIL);
                jsonResult.setMessage("数据不能为空");
                return new ResponseEntity(jsonResult, HttpStatus.OK);
            }
            userService.updateMobile(param);
        } catch (ServiceRuntimeException e) {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
            return new ResponseEntity(jsonResult, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
            return new ResponseEntity(jsonResult, HttpStatus.OK);
        }
        return new ResponseEntity(jsonResult, HttpStatus.OK);
    }

    @RequestMapping(value = "/tencent", method = RequestMethod.POST, consumes = MediaTypes.JSON, produces = MediaTypes.JSON_UTF_8)
    public ResponseEntity<?> tencent(@RequestBody String param) {
        JsonResult jsonResult = new JsonResult();
        try {
            if (StringUtils.isBlank(param)) {
                jsonResult.setCode(JsonResult.CODE_FAIL);
                jsonResult.setMessage("数据不能为空");
                return new ResponseEntity(jsonResult, HttpStatus.OK);
            }
            User user = userService.tencent(param, ConfigUtil.getClientId());
            if (user != null) {
                Volunteer volunteer = this.volunteerService.findByUserId(user.getId());
                jsonResult.setMessage("登录成功");
                jsonResult.setCode(JsonResult.CODE_SUCCESS);
                jsonResult.setData(volunteer);
                return new ResponseEntity(jsonResult, HttpStatus.OK);
            } else {
                String message = "第三方登录失败";
                jsonResult.setMessage(message);
                jsonResult.setCode(JsonResult.CODE_FAIL);
                return new ResponseEntity(jsonResult, HttpStatus.OK);
            }

        } catch (ServiceRuntimeException e) {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
            return new ResponseEntity(jsonResult, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
            return new ResponseEntity(jsonResult, HttpStatus.OK);
        }
    }

    @RequestMapping(value = "/sina", method = RequestMethod.POST, consumes = MediaTypes.JSON, produces = MediaTypes.JSON_UTF_8)
    public ResponseEntity<?> sina(@RequestBody String param) {
        JsonResult jsonResult = new JsonResult();
        try {
            if (StringUtils.isBlank(param)) {
                jsonResult.setCode(JsonResult.CODE_FAIL);
                jsonResult.setMessage("数据不能为空");
                return new ResponseEntity(jsonResult, HttpStatus.OK);
            }
            User user = userService.sina(param, ConfigUtil.getClientId());
            if (user != null) {
                Volunteer volunteer = this.volunteerService.findByUserId(user.getId());
                jsonResult.setMessage("登录成功");
                jsonResult.setCode(JsonResult.CODE_SUCCESS);
                jsonResult.setData(volunteer);
                return new ResponseEntity(jsonResult, HttpStatus.OK);
            } else {
                String message = "第三方登录失败";
                jsonResult.setMessage(message);
                jsonResult.setCode(JsonResult.CODE_FAIL);
                return new ResponseEntity(jsonResult, HttpStatus.OK);
            }

        } catch (ServiceRuntimeException e) {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
            return new ResponseEntity(jsonResult, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
            return new ResponseEntity(jsonResult, HttpStatus.OK);
        }
    }

    @RequestMapping(value = "/wechat", method = RequestMethod.POST, consumes = MediaTypes.JSON, produces = MediaTypes.JSON_UTF_8)
    public ResponseEntity<?> wechat(@RequestBody String param) {
        JsonResult jsonResult = new JsonResult();
        try {
            if (StringUtils.isBlank(param)) {
                jsonResult.setCode(JsonResult.CODE_FAIL);
                jsonResult.setMessage("数据不能为空");
                return new ResponseEntity(jsonResult, HttpStatus.OK);
            }
            User user = userService.wechat(param, ConfigUtil.getClientId());
            if (user != null) {
                Volunteer volunteer = this.volunteerService.findByUserId(user.getId());
                jsonResult.setMessage("登录成功");
                jsonResult.setCode(JsonResult.CODE_SUCCESS);
                jsonResult.setData(volunteer);
                return new ResponseEntity(jsonResult, HttpStatus.OK);
            } else {
                String message = "第三方登录失败";
                jsonResult.setMessage(message);
                jsonResult.setCode(JsonResult.CODE_FAIL);
                return new ResponseEntity(jsonResult, HttpStatus.OK);
            }

        } catch (ServiceRuntimeException e) {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
            return new ResponseEntity(jsonResult, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
            return new ResponseEntity(jsonResult, HttpStatus.OK);
        }
    }

    @RequestMapping(value = "/otherSign", method = RequestMethod.POST, consumes = MediaTypes.JSON, produces = MediaTypes.JSON_UTF_8)
    public ResponseEntity<?> otherSign(@RequestBody String param) {
        log.info(param);
        JsonResult jsonResult = new JsonResult();

        try {
            if (StringUtils.isBlank(param)) {
                jsonResult.setCode(JsonResult.CODE_FAIL);
                jsonResult.setMessage("数据不能为空");
                return new ResponseEntity(jsonResult, HttpStatus.OK);
            }

            User user = userService.signIn(param, ConfigUtil.getClientId());

            if (user != null) {
                Volunteer volunteer = this.volunteerService.findByUserId(user.getId());
                jsonResult.setMessage("登录成功");
                jsonResult.setCode(JsonResult.CODE_SUCCESS);
                jsonResult.setData(volunteer);
                return new ResponseEntity(jsonResult, HttpStatus.OK);
            } else {
                String message = "第三方登录失败";
                jsonResult.setMessage(message);
                jsonResult.setCode(JsonResult.CODE_FAIL);
                return new ResponseEntity(jsonResult, HttpStatus.OK);
            }

        } catch (ServiceRuntimeException e) {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
            return new ResponseEntity(jsonResult, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
            return new ResponseEntity(jsonResult, HttpStatus.OK);
        }
    }

}
